function visual_analysis(arg1, arg2)
%
% visual analysis displays the data and allows the cursor to provide windows
%
global CONTROL DFILE ALLCH BK_CH
persistent toggleflag
persistent ax1 ax2 avg ti baseline time
persistent X Y vimode
persistent zoomlevel zooms
persistent idselect hidselect hfit hpick
persistent nc
persistent pickflag pickx picky
persistent a0 a1 tau tau1 tau2 a2

fsize = 7;
msize = 3;
xs = 0.5;
gr = 4/3;
bo = 0.04;
pos1 = [bo bo xs*gr xs];
pos2 = [bo 2*bo+xs xs*gr (1-(xs+3*bo))];
msg_pos1 = [bo+(xs*gr)+bo bo 0.12 0.05];
msg_pos2 = [bo+(xs*gr)+bo bo 0.12 0.05];
if(isempty(vimode)) vimode = -1; end;
if(isempty(zooms)) zooms={}; zoomlevel = 1; end;
if(isempty(idselect)) idselect = 0; hidselect = []; end;
if(isempty(hfit)) hfit = []; end;
if(isempty(hpick)) hpick = []; end;
if(isempty(a0))
    a0 = 0; a1 = 1; a2 = 1; tau = 5; tau1 = 5; tau2 = 50;
end;
if(isempty(pickflag)) pickflag = 0; end;
if(pickflag == 0)
    pickx = [];
    picky = [];
end;
%if(isempty(time))
        time = make_time(DFILE);
    tmax = max(max(time'));
%end;



if(nargin == 0)
    toggleflag = 0;
    sf = getmainselection;
    if(length(sf) > 1)
        sf = sf(1);
    end;
    X = [];
    Y = [];
    baseline = [];

    h = findobj('Tag', 'Visual'); % check for pre-existing window
    if(isempty(h)) % if none, make one
        if(isempty(h))
            open('va.fig');
        end;
        h = findobj('tag', 'Visual');
        % Use system color scheme for figure:
    end
    figure(h); % otherwise, select it
    set(h,'Color',get(0,'defaultUicontrolBackgroundColor'));

    hf1=findobj('tag', 'va_axes1');
    hf2=findobj('tag', 'va_axes2');
    if(~isempty(hf1))
        delete(hf1);
    end;
    if(~isempty(hf2))
        delete(hf2);
    end;


    %Command Menu
    %uimenu('Label', 'Close &Window', 'Position', 1, 'callback', 'close(findobj(''Tag'', ''Visual''));' );
    %uimenu('Label', '&Print', 'Callback', 'print;');
    %uimenu('Label', 'Print&Setup', 'Callback', 'printdlg;');
    set(h, 'Name', sprintf('Visual Analysis - File: %s', CONTROL(sf).filename))

    time = make_time(DFILE);
    tmax = max(max(time'));
    % First plot:
    %plot voltage
    h_ax1=subplot('Position',pos1);

    if(vimode == -1) % new call?
        if(DFILE.dmode == 'VC')
            vimode = 2;
        else
            vimode = 1;
        end;
    end;
    plot(time(1,:)', ALLCH{vimode}', '-k');
    set(gca, 'FontSize', fsize);
    set(h_ax1, 'Position', pos1);
    ylabel(CONTROL(sf).V_Unit);
    u=get(gca, 'YLim');
    v=get(gca, 'XLim');
    v(2)=tmax;
    set(gca, 'Xlim', v);
    set(h_ax1, 'tag', 'va_axes1');
    datac_setcrosshair(h_ax1, 'va_axes1info', 'ms', 'mV', msg_pos1);

    set(h,   'WindowButtonMotionFcn', 'visual_analysis(''mouse_motion'', gcbf);', ...
        'WindowButtonDownFcn', 'visual_analysis(''mouse_down'', gcbf);', ...
        'WindowButtonUpFcn', 'visual_analysis(''mouse_up'', gcbf);', ...
        'NumberTitle', 'off');
    return;
end;


switch arg1
    case 'viswitch'
        if(vimode == 1) % means VOLTAGE
            vimode = 2; % means Current
            htog = findobj('tag', 'VIToggle');
            if(~isempty(htog) & ishandle(htog))
                set(htog, 'String', 'Show V');
                visual_analysis('redisplay raw');
                return;
            end;
        else
            vimode = 1;
            htog = findobj('tag', 'VIToggle');
            if(~isempty(htog) & ishandle(htog))
                set(htog, 'String', 'Show I');
                visual_analysis('redisplay raw');
                return;
            end;
        end;
    case 'setch1'
        vimode = 1;
        visual_analysis('dispwzoom');
    case 'setch2'
        vimode = 2;
        visual_analysis('dispwzoom');
    case 'setch3'
        vimode = 3;
        visual_analysis('dispwzoom');
    case 'setch4'
        vimode = 4;
        visual_analysis('dispwzoom');

    case 'pick'
        pickflag = 1;

    case 'clearpick'
        pickflag = 0;
        pickx = [];
        picky = [];
        hpick2 = findobj('tag', 'va_npick');
        set(hpick2, 'string', 'N: 0');
        if(~isempty(hpick) & ishandle(hpick))
            set(hpick, 'Xdata', []);
            set(hpick, 'Ydata', []);
            delete(hpick);
            drawnow;
        end;

    case 'mouse_down'
        datac_do_ptr(arg2, 1);
        if(pickflag)
            axinfo = get(gca, 'UserData'); % There may be information in userdata we can use
            if(isfield(axinfo, 'curpos'))
                pickx = [pickx axinfo.curpos(1)];
                picky = [picky axinfo.curpos(2)];
            end;
            % keep x and y sorted.
            [pickx, j] = sort(pickx);
            picky = picky(j);
            if(isempty(hpick) | ~ishandle(hpick))
                hpick = line(pickx, picky);
                set(hpick, 'color', 'blue', 'marker', '+', 'linestyle', 'none');
            else
                set(hpick, 'XData', pickx);
                set(hpick, 'YData', picky);
            end;
            hpick2 = findobj('tag', 'va_npick');
            set(hpick2, 'string', sprintf('N: %d', length(pickx)));
        end;

    case 'mouse_up'
        datac_do_ptr(arg2, 2); % ctl should point to figure window...
    case 'mouse_motion'
        datac_do_ptr(arg2, 0); % ctl should point to figure window...

    case 'zoomplus'
        if(zoomlevel == 1)
            zooms{zoomlevel} = [get(gca, 'Xlim'), get(gca, 'YLim')];
        end;
        h_axes = findobj('tag', 'va_axes1');
        axinfo = get(h_axes, 'UserData'); % There may be information in userdata we can use
        if(isfield(axinfo, 'down_pos'))
            ax1 = axinfo.down_pos;
            ax2 = axinfo.up_pos;
        else
            return;
        end;
        % and now redraw the display
        u=get(gca, 'YLim');
        if(ax1(1) == ax2(1))
            ax2(1) = ax1(1)+1;
        end;
        if(ax1(2) == ax2(2))
            ax2(2) = ax1(2)+1;
        end;
        xa = sort([ax1(1) ax2(1)]);
        ya = sort([ax1(2) ax2(2)]);
        h_ax1=findobj('tag', 'va_axes1');
        set(h_ax1, 'Position', pos1);
        set(gca, 'XLim', xa);
        set(gca, 'Ylim', ya);
        setviaxes(vimode, h_ax1, msg_pos1);

        zoomlevel = zoomlevel + 1;
        zooms{zoomlevel} = [xa, ya]; % save the axis sizes...

    case 'zoomminus'
        zoomlevel = zoomlevel - 1;
        if(zoomlevel < 1)
            zoomlevel = 1;
            return;
        end;
        h_axes = findobj('tag', 'va_axes1');
        % and now redraw the display
        u=get(gca, 'YLim');
        [x] = zooms{zoomlevel};
        xa = x(1:2);
        ya = x(3:4);
        h_ax1=findobj('tag', 'va_axes1');
        set(h_ax1, 'Position', pos1);
        set(gca, 'XLim', xa);
        set(gca, 'Ylim', ya);
        setviaxes(vimode, h_ax1, msg_pos1)

    case 'dispwzoom'
        h_axes = findobj('tag', 'va_axes1');
        set(gcf, 'CurrentAxes', h_axes);
        % and now redraw the display
        plot(time(1,:)', ALLCH{vimode}, '-k');
        set(gca, 'tag', 'va_axes1');
        setviaxes(vimode, h_axes, msg_pos1)

        if(zoomlevel <= 1)
            zoomlevel = 1;
            return;
        end;
        [x] = zooms{zoomlevel};
        xa = x(1:2);
        ya = x(3:4);
        set(gca, 'XLim', xa);
      %  set(gca, 'Ylim', ya);

    case 'copypicktowindow'
        if(~pickflag)
            return;
        end;
        if(length(pickx) < 2)
            QueMessage ('Note enough points to set window');
            return;
        end;
        setfitwin(pickx(1), pickx(2));
   
    
    case 'fitwinselect'
        if(zoomlevel == 1)
            zooms{zoomlevel} = [get(gca, 'Xlim'), get(gca, 'YLim')];
        end;
        [x1, x2] = getfitwin;

        h_axes = findobj('tag', 'va_axes1');
        axinfo = get(h_axes, 'UserData'); % We are going to set the userdata...
        if(isfield(axinfo, 'down_pos'))
            ax1 = axinfo.down_pos;
            ax2 = axinfo.up_pos;
        else
            return;
        end;
        ax1(1) = x1;
        ax2(1) = x2; % force new values
        ay = get(gca, 'YLim');
        ax1(2) = ay(1);
        ax2(2) = ay(2);
        axinfo.down_pos = ax1;
        axinfo.up_pos = ax2;
        % and now redraw the display
        if(ax1(1) == ax2(1))
            ax2(1) = ax1(1)+1;
        end;
        if(ax1(2) == ax2(2))
            ax2(2) = ax1(2)+1;
        end;
        xa = sort([ax1(1) ax2(1)]);
        ya = sort([ax1(2) ax2(2)]);
        h_ax1=findobj('tag', 'va_axes1');
        set(h_ax1, 'Position', pos1);
        set(gca, 'XLim', xa);
        set(gca, 'Ylim', ya);
        setviaxes(vimode, h_ax1, msg_pos1)
        zoomlevel = zoomlevel + 1;
        zooms{zoomlevel} = [xa, ya]; % save the axis sizes...

    case 'filter'
        BK_CH = ALLCH;
        h_dvmax=findobj('tag', 'va_dvmax');
        h_bdur = findobj('tag', 'va_filtms');
        dvmax = abs(str2num(get(h_dvmax, 'string')));
        bdur = str2num(get(h_bdur, 'string'));
        r = DFILE.rate(1)/1000;
        idur = floor(bdur/r)
        
            [ic, jc] = find(abs(diff(ALLCH{vimode})) > dvmax);            
            for ik = 1:length(ic)
                if(jc(ik) == 1)
                    jc(ik) = 2;
                end;
                ALLCH{vimode}(ic(ik), jc(ik)-1:jc(ik)+idur) = ALLCH{vimode}(ic(ik), jc(ik)-2);
            end;
        
        visual_analysis('dispwzoom');
        
    case 'defilter'
        if(~isempty(BK_CH))
            ALLCH = BK_CH;
        end;
        
    case 'Reset scale' % rescale the data to "show all"
        disp 'rescale'
        time = make_time(DFILE);
        tmax = max(max(time'));
        h_ax1=findobj('tag', 'va_axes1');
        set(h_ax1, 'XLim', [0 tmax]);
        set(h_ax1, 'Position', pos1);

        vmax = max(max(ALLCH{vimode}));
        vmin = min(min(ALLCH{vimode}));
        set(h_ax1, 'YLim', [vmin vmax]);
        set(gca, 'tag', 'va_axes1');
        setviaxes(vimode, h_ax1, msg_pos1)
        avg = [];
        bflag = 0;
        nc = [];
        idselect = 0;
        zoomlevel = 1;
        if(~isempty(hfit))
            delete hfit;
        end;

        return;

    case 'redisplay raw'
        visual_analysis('clearpick'); % remove the picked plot first if it is present.
        toggleflag = 0;
        sf = getmainselection;
        if(length(sf) > 1)
            sf = sf(1);
        end;
        fsize = 7;
        msize = 3;
        bflag = 0;
        time = make_time(DFILE);
        tmax = max(max(time'));
        h_ax1=findobj('tag', 'va_axes1');
        set(gcf, 'CurrentAxes', h_ax1);
        set(h_ax1, 'Position', pos1);
        if(vimode == -1) % new call?
            if(DFILE.dmode == 'VC')
                vimode = 2;
            else
                vimode = 1;
            end;
        end;


        plot(time(1,:)', ALLCH{vimode}', '-k');

        set(gca, 'FontSize', fsize);
        ylabel(CONTROL(sf).V_Unit);
        u=get(gca, 'YLim');
        v=get(gca, 'XLim');
        v(2)=tmax;
        set(gca, 'Xlim', v);
        set(gca, 'tag', 'va_axes1');
        setviaxes(vimode, h_ax1, msg_pos1);

        baseline = 0;
        bflag = 0;
        avg = [];
        nc = []; % clear the list of handles...
        idselect = 0;
        zoomlevel = 1;
        if(~isempty(hfit) & ishandle(hfit))
            delete hfit;
        end;
        nc = get(gca, 'Children');
        hsel = findobj('tag', 'va_fig_wselect');
        set(hsel, 'min', 1);
        set(hsel, 'max', length(nc));
        ls = ['1'];
        for i = 2:length(nc)
            ls = [ls '|' sprintf('%d', i)];
        end;
        set(hsel, 'String', ls);
        cv = get(hsel, 'Value');
        if(cv > length(nc) | cv < 1)
            set(hsel, 'Value', 1);
        else
            set(hsel, 'Value', cv);
        end;
        return;

    case 'average' % compute average in the window and display it
        disp 'average'
        time = make_time(DFILE);
        tmax = max(max(time'));
        h_ax1=findobj('tag', 'va_axes1');
        tx = get(h_ax1, 'XLim'); % get the visible x axis limits
        ti = find_times(tx);
        j = find(ti > size(ALLCH{vimode},2));
        ti(j) = size(ALLCH{vimode},2);
        avg = mean(ALLCH{vimode}(:,[ti(1):ti(2)]));
        set(gcf, 'CurrentAxes', h_ax1);
        set(h_ax1, 'Position', pos1);
        cla;
        hl=line(time(1,ti(1):ti(2))', avg);
        u(1)=min(avg);
        u(2)=max(avg);
        set(gca, 'Ylim', u);
        set(hl, 'color', 'blue');
        set(gca, 'tag', 'va_axes1');
        setviaxes(vimode, h_ax1, msg_pos1);

    case 'baseline'
        disp 'baseline'
        time = make_time(DFILE);
        tmax = max(max(time'));
        hax1=findobj('tag', 'va_axes1');
        axinfo = get(hax1, 'UserData'); % There may be information in userdata we can use
        ax1 = axinfo.down_pos;
        ax2 = axinfo.up_pos;

        baseline = mean(ALLCH{vimode}([ax1(1):ax2(1)])');
        bflag = 1;
        set(gcf, 'CurrentAxes', hax1);
        set(hax1, 'Position', pos1);
        cla;

        for i = 1:size(ALLCH{i},1)
            hl=line(time(i,:)', ALLCH{i}-baseline(i));
        end;
        set(hl, 'color', 'blue');
        set(gca, 'tag', 'va_axes1');
        setviaxes(vimode, h_ax1, msg_pos1);

    case 'indiv_spec'
        disp 'Spectra of all traces'
        time = make_time(DFILE);
        flomb = [1:300];
        prob = 0.05; % use 5% level to set
        n=size(ALLCH{1},1); % number of traces to analyze
        h_ax1=findobj('tag', 'va_axes1');
        set(gcf, 'CurrentAxes', h_ax1);
        set(h_ax1, 'Position', pos1);
        % cla;
        h_ax2 = findobj('tag', 'va_axes2');
        if(isempty(h_ax2))
            h_ax2=subplot('Position',pos2);
            set(h_ax2, 'tag', 'va_axes2');
        end;
        axes(h_ax2);
        cla;
        tx = get(h_ax1, 'XLim'); % get the visible x axis limits
        ti = find_times(tx);
        axes(h_ax2); % plot the computation.
        hold on;
        for i = 1:n
            T = time(1, ti(1):ti(2))';

            p = polyfit(T, ALLCH{vimode}(i,ti(1):ti(2))', 2);
            Vp = ALLCH{vimode}(i,ti(1):ti(2))' - (p(1)*T.^2 +p(2)*T+ p(3));

            setviaxes(vimode, h_ax1, msg_pos1);
            % window the data.
            w = hanning(length(Vp), 'symmetric');
            win_mag = sum(w)/length(w);
            Vp = Vp .* w;
            axes(h_ax2); % plot the computation.
            hl=plot(T, Vp);
            hold on;
            set(hl, 'color', 'blue');

            n_pts = floor(length(Vp)/2);
            % Lomb's PSD method
            [fl, Pvl, conf] = lombpsd2(T/1000, Vp, flomb, prob);
            Pvl = sqrt((Pvl * 2 * var(Vp))/n_pts)/win_mag; % remove normalization and correct for window
            %axes(h_ax2);
            % plot(fl, Pvl, '-k');
            %hold on;
            %drawnow
            X(i,:) = fl;
            Y(i,:) = Pvl;
        end;
        ym=mean(Y);
        ys=std(Y)/sqrt(size(Y,1));
        axes(h_ax2);
        plot(X, ym, '-r'); % show mean
        hold on;
        plot(X, ym-ys, '-b');
        plot(X, ym+ys, '-b');
        drawnow
        setviaxes(vimode, h_ax1, msg_pos1);


    case 'spectrum'
        disp 'spectrum on averaged signal'
        if(isempty(avg))
            return;
        end;
        time = make_time(DFILE);
        flomb = [1:300];
        prob = 0.05; % use 5% level to set
        V = avg';
        T = time(1, ti(1):ti(2))';

        p = polyfit(T, V, 2);
        Vp = V - (p(1)*T.^2 +p(2)*T+ p(3));
        avg = Vp;
        h_ax1=findobj('tag', 'va_axes1');
        set(gcf, 'CurrentAxes', h_ax1);
        set(h_ax1, 'Position', pos1);
        cla;
        hl=plot(T, Vp);
        set(hl, 'color', 'blue');
        set(gca, 'tag', 'va_axes1');
        setviaxes(vimode, gca, msg_pos1);
        % window the data.
        w = hanning(length(Vp), 'symmetric');
        win_mag = sum(w)/length(w);
        Vp = Vp .* w;
        n_pts = floor(length(Vp)/2);
        % Lomb's PSD method
        [fl, Pvl, conf] = lombpsd2(T/1000, Vp, flomb, prob);
        Pvl = sqrt((Pvl * 2 * var(Vp))/n_pts)/win_mag; % remove normalization and correct for window
        h_ax2=subplot('Position',pos2);
        plot(fl, Pvl, '-k');
        X = fl;
        Y = Pvl;
        set(gca, 'tag', 'va_axes2');
        setviaxes(vimode, h_ax1, msg_pos1);


    case 'slope'
        disp 'slope'
        time = make_time(DFILE);
        tmax = max(max(time'));
        hax1=findobj('tag', 'va_axes1');
        tx = get(hax1, 'XLim'); % get the visible x axis limits
        ti = find_times(tx);
        l = size(ALLCH{1});
        m=[];
        b=[];
        for i = 1:l(1)
            [m(i) b(i)] = linreg(time(i,[ti(1):ti(2)]), ALLCH{vimode}((i),[ti(1):ti(2)]));
        end;
        zt = DFILE.ztime - DFILE.ztime(1);
        hax2 = findobj('tag', 'va_axes2');
        if(isempty(hax2))
            hax2=subplot('Position',pos2);
        else
            set(hax2, 'Position', pos2);
            set(gcf, 'CurrentAxes', hax2);
            cla;
        end;
        hl=plot(zt, m);
        X = zt;
        Y = m;
        set(hl, 'color', 'blue');
        set(gca, 'tag', 'va_axes2');
        setviaxes(vimode, h_ax1, msg_pos1);

    case 'rms'
        disp 'RMS'
        time = make_time(DFILE);
        tmax = max(max(time'));
        hax1=findobj('tag', 'va_axes1');
        tx = get(hax1, 'XLim'); % get the visible x axis limits
        ti = find_times(tx);
        l = size(ALLCH{1});
        m=[];
        b=[];
        rms = [];
        for i = 1:l(1)
            T = time(i,[ti(1):ti(2)]);

            V = ALLCH{vimode}(i,[ti(1):ti(2)]);
            [m(i) b(i)] = linreg(T, V);
            r = V - (m(i)*T+b(i));
            rms(i) = sqrt(sum(r.*r)/length(r));
        end;

        zt = DFILE.ztime - DFILE.ztime(1);
        hax2 = findobj('tag', 'va_axes2');
        if(isempty(hax2))
            hax2=subplot('Position',pos2);
        else
            set(hax2, 'Position', pos2);
            set(gcf, 'CurrentAxes', hax2);
            cla;
        end;
        hl=plot(zt, rms, 'marker', 'o', 'markersize', 2, 'markerfacecolor', 'k', 'color', 'k');
        X = zt;
        Y = rms;
        set(hl, 'color', 'blue');
        set(gca, 'tag', 'va_axes2');
        setviaxes(vimode, h_ax1, msg_pos1);

    case 'showall'
        if(isempty(nc))
            nc = get(gca, 'Children');
        end;
        if(~isempty(nc))
            set(nc, 'Color', 'black', 'visible', 'on');
            if(idselect > 0)
                set(nc(idselect), 'Color' , 'green', 'visible', 'on');
                drawnow
            end;
        end;


    case 'select2' % selection from the LIST BOX, not from the nearest trace.
        h_axes = findobj('tag', 'va_axes1');
        axinfo = get(h_axes, 'UserData'); % There may be information in userdata we can use
        if(isfield(axinfo, 'down_pos'))
            ax1 = axinfo.down_pos;
            ax2 = axinfo.up_pos;
        else
            return;
        end;
        % that should get us the position. Now we need to find the data set that is
        % has the closest point, and replot it with green color (changing all the
        % others to black again).

        if(isempty(nc))
            nc = get(gca, 'Children');
        end;
        hnc = get(nc); % get the handles
        hsel = findobj('tag', 'va_fig_wselect');
        id = get(hsel, 'Value');

        set(nc, 'Color', 'black', 'visible', 'off');
        if(id > 0)
            set(nc(id), 'Color' , 'green', 'visible', 'on');
            drawnow
        end;
        idselect = id;
        hidselect = hnc(id); % save the handle too... faster access to data.

        show_referencechannel(id, ax1, ax2, vimode);


    case 'waveform_select'
        h_axes = findobj('tag', 'va_axes1');
        axinfo = get(h_axes, 'UserData'); % There may be information in userdata we can use
        if(isfield(axinfo, 'down_pos'))
            ax1 = axinfo.down_pos;
            ax2 = axinfo.up_pos;
        else
            return;
        end;
        % that should get us the position. Now we need to find the data set that is
        % has the closest point, and replot it with green color (changing all the
        % others to black again).

        if(isempty(nc))
            nc = get(gca, 'Children');
        end;
        hnc = get(nc); % get the handles
        dmin = -1;
        d = 0;
        id = 0;
        for i = 1:length(hnc)
            if(hnc(i).Type == 'line')
                xd = hnc(i).XData;
                yd = hnc(i).YData;
                d = min(sqrt((xd-ax1(1)).^2 + (yd - ax1(2)).^2));
                if(dmin == -1)
                    dmin = d;
                    id = i;
                else
                    if(d < dmin) dmin = d; id = i; end;
                end;
            end;
        end;
        set(nc, 'Color', 'black', 'visible', 'off');
        if(id > 0)
            set(nc(id), 'Color' , 'green', 'visible', 'on');
            drawnow
        end;
        idselect = id;
        hidselect = hnc(id); % save the handle too... faster access to data.
        ht = findobj('tag', 'va_fig_wselect');
        set(ht, 'Min', 1);
        set(ht, 'Max', length(hnc));
        if(~isempty(ht))
            set(ht,'Value', id);
        end;
        show_referencechannel(id, ax1, ax2, vimode);


    case 'linfit' % fit a line to the selected trace.
        if(idselect == 0 & pickflag == 0) return; end;
        [xd, yd, nc] = getdataplot(nc, idselect, pickflag, pickx, picky);

        [m, b, r, p] = linreg(xd, yd);
        yp = m * xd + b;
        if(isempty(hfit) | ~ishandle(hfit))
            hfit = line(xd, yp);
            set(hfit, 'color', 'red');
        else
            set(hfit, 'Xdata', xd);
            set(hfit, 'Ydata', yp);
        end;

        ht = findobj('tag', 'va_fig_textbox');
        if(~isempty(ht))
            set(ht,'String', sprintf('Y = %f * X + %f\nr = %6.2f\np = %7.3f', m, b, r, p));
        end;

    case 'expfit_1' % fit a line to the selected trace with an exponential function.
        if(idselect == 0 & pickflag == 0) return; end;
        h_axes = findobj('tag', 'va_axes1');
        [xd, yd, nc] = getdataplot(nc, idselect, pickflag, pickx, picky);

        [a0 a1 tau] = expfit((xd-xd(1)), yd);

        yp = a0 + a1*exp(-(xd-xd(1))/tau);
        if(isempty(hfit) | ~ishandle(hfit))
            hfit = line(xd, yp);
            set(hfit, 'color', 'red');
        else
            set(hfit, 'Xdata', xd);
            set(hfit, 'Ydata', yp);
        end;

        ht = findobj('tag', 'va_fig_textbox');
        if(~isempty(ht))
            set(ht,'String', sprintf('Exp 1:\nY = %f + %f*exp(-t/%f)', a0, a1, tau));
        end;

    case 'seedexp2'
        % use exp 1 results to see exp2 data
        setfitpars(a0, a1/2, tau, a1/2, tau*10);

    case 'expfit_2' % fit a line to the selected trace with an exponential function.
        if(idselect == 0 & pickflag == 0) return; end;
        [xd, yd, nc] = getdataplot(nc, idselect, pickflag, pickx, picky);

        %[a0 a1 tau] = expfit((xd-xd(1)), yd);
        [a0, a1, tau1, a2, tau2, lockarray] = getfitpars; % read from the window
        % NOTE: we flip the lockarray in the call, as 1 is checked, but 1 means vary in the
        % mrqfit call -
        mqlock = 1-lockarray;
        [fpar2, chisq2, niter2, vfit] = mrqfit('exponential', [a0 a1 tau1 a2 tau2], xd-xd(1), yd, [], ...
            mqlock, [], [], 250, []);
        amp2 = fpar2(1); amp21=fpar2(2); tau21 = fpar2(3); amp22 = fpar2(4); tau22 = fpar2(5);

        if(isempty(hfit) | ~ishandle(hfit))
            hfit = line(xd, vfit);
            set(hfit, 'color', 'red');
        else
            set(hfit, 'Xdata', xd);
            set(hfit, 'Ydata', vfit);
        end;

        ht = findobj('tag', 'va_fig_textbox');
        if(~isempty(ht))
            set(ht,'String', sprintf('Exp 2:\nY = %f + %f * exp(-t/%f) + %f * exp(-t/%f)',...
                amp2, amp21, tau21, amp22, tau22));
        end;

        setfitpars(amp2, amp21, tau21, amp22, tau22); % update the parameter window values.

    case 'export'
        % print out the results from the analysis (fitting results - exp2)

        [t0 t1] = getfitwin();
        [a0, a1, tau1, a2, tau2, lock] = getfitpars();
        hcmd = findobj('tag', 'va_commandvalue');
        vref = str2double(get(hcmd, 'string'));

        fprintf(1, '%s\t%4d\t%4d\t%6.1f\t%7.2f\t%7.2f\t%.2f\t%.2f\t%.3f\t%.2f\t%.3f\n', ...
            DFILE.filename, DFILE.frec, DFILE.lrec, vref, t0, t1, a0, a1, tau1, a2, tau2);

    case 'export_toworkspace'
        if(isempty(X) | isempty(Y))
            return;
        end;
        if(length(X) ~= length(Y))
            return;
        end;
        assignin('base', 'X', X);
        assignin('base', 'Y', Y);

    otherwise
end;

function [x1, x2] = getfitwin() % read the fit win values...
hw = findobj('tag', 'va_awin1');
x1 = number_arg(get(hw, 'string'));
hw = findobj('tag', 'va_awin2');
x2 = number_arg(get(hw, 'string'));
return;

function setfitwin(x1, x2)
hw = findobj('tag', 'va_awin1');
set(hw, 'string', num2str(x1));
hw = findobj('tag', 'va_awin2');
set(hw, 'string', num2str(x2));
return;

function [a0, a1, tau1, a2, tau2, lockarray] = getfitpars()
hw = findobj('tag', 'va_par_a0');
a0 = number_arg(get(hw, 'string'));
hw = findobj('tag', 'va_lock_a0');
la0 = get(hw, 'value');

hw = findobj('tag', 'va_par_a1');
a1 = number_arg(get(hw, 'string'));
hw = findobj('tag', 'va_lock_a1');
la1 = get(hw, 'value');

hw = findobj('tag', 'va_par_tau1');
tau1 = number_arg(get(hw, 'string'));
hw = findobj('tag', 'va_lock_tau1');
lt1 = get(hw, 'value');

hw = findobj('tag', 'va_par_a2');
a2 = number_arg(get(hw, 'string'));
hw = findobj('tag', 'va_lock_a2');
la2 = get(hw, 'value');

hw = findobj('tag', 'va_par_tau2');
tau2 = number_arg(get(hw, 'string'));
hw = findobj('tag', 'va_lock_tau2');
lt2 = get(hw, 'value');

lockarray = [la0 la1 lt1 la2 lt2]; % build the lock array.
return;

function  setfitpars(a0, a1, tau1, a2, tau2)
hw = findobj('tag', 'va_lock_a0');
la0 = get(hw, 'value');
if(la0 == 0) % only set if NOT locked
    hw = findobj('tag', 'va_par_a0');
    set(hw, 'string', num2str(a0, 5));
end;

hw = findobj('tag', 'va_lock_a1');
la1 = get(hw, 'value');
if(la0 == 0) % only set if NOT locked
    hw = findobj('tag', 'va_par_a1');
    set(hw, 'string', num2str(a1, 5));
end;
hw = findobj('tag', 'va_lock_a2');
la2 = get(hw, 'value');
if(la1 == 0) % only set if NOT locked
    hw = findobj('tag', 'va_par_a2');
    set(hw, 'string', num2str(a2, 5));
end;
hw = findobj('tag', 'va_lock_tau1');
lt1 = get(hw, 'value');
if(lt1 == 0) % only set if NOT locked
    hw = findobj('tag', 'va_par_tau1');
    set(hw, 'string', num2str(tau1, 5));
end;
hw = findobj('tag', 'va_lock_tau2');
lt2 = get(hw, 'value');
if(lt2 == 0) % only set if NOT locked
    hw = findobj('tag', 'va_par_tau2');
    set(hw, 'string', num2str(tau2, 5));
end;

return;


function show_referencechannel(id, ax1, ax2, vimode)
% now get the mean of the other channel (v or i) and display the
% value for reference.
global ALLCH


xl = get(gca, 'Xlim');
huse = findobj('tag', 'va_usefitwin');
usewin = get(huse, 'Value'); % checkbox for using the window
if(usewin)
    [x1, x2] = getfitwin;
    xl = [x1 x2];
end;
id2 = size(ALLCH{1},1)-id+1;

ti = find_times(xl);
switch(vimode)
    case 1 % note - swapped from the usual - this is because we look for the OTHER chan.
        avg = mean(ALLCH{vimode}(id2,[ti(1):ti(2)]));
    case 2
        avg = mean(ALLCH{vimode}(id2,[ti(1):ti(2)]));
    otherwise
        avg = mean(ALLCH{vimode}(id2,[ti(1):ti(2)]));
end;
hcmd = findobj('tag', 'va_commandvalue');
set(hcmd, 'string', num2str(avg));

return;

function [xd, yd, nc] = getdataplot(nc, idselect, pickflag, pickx, picky)
xd=[];
yd=[];
nc = 0;
h_axes = findobj('tag', 'va_axes1');
axinfo = get(h_axes, 'UserData'); % There may be information in userdata we can use
if(isfield(axinfo, 'down_pos'))
    ax1 = axinfo.down_pos;
    ax2 = axinfo.up_pos;
else
    return;
end;
% that should get us the position. Now we need to find the data set that is
% has the closest point, and replot it with red color (changing all the
% others to black again).
hnc = get(gca, 'Children');
%hnc = get(nc); % get the handles
if(pickflag == 0)
    xd = hnc(idselect).XData;
else
    xd = pickx;
end;
xl = get(gca, 'Xlim');

huse = findobj('tag', 'va_usefitwin');
usewin = get(huse, 'Value'); % checkbox for using the window
if(usewin)
    [x1, x2] = getfitwin;
    xl = [x1 x2];
end;

yl = get(gca, 'YLim');
ix0 = min(find(xd > xl(1)));
ix1 = max(find(xd < xl(2)));
xd = xd(ix0:ix1);
if(pickflag == 0)
    yd = hnc(idselect).YData(ix0:ix1);
else
    yd = picky(ix0:ix1);
end;
return;


function m = gslope(ignored)
%GSLOPE Estimate a slope from two mouse clicks.
%   GSLOPE creates a crosshair in the current figure and waits for two mouse
%   clicks. The slope of the line through the two click locations is
%   returned. Logarithmic scales are automatically accounted for.
%
%   See also GINPUT.

% Copyright 1999-2003 by Toby Driscoll (driscoll@math.udel.edu).

[x,y]=ginput(2);
if nargin > 0
    line(x,y,'linesty','none','marker','+','linestyle','--','color','r')
end
if strcmp(get(gca,'xsc'),'log'), x = log10(x); end
if strcmp(get(gca,'ysc'),'log'), y = log10(y); end
m = diff(y)/diff(x);


function setviaxes(vimode, h_ax1, msg_pos1)
switch(vimode)
    case {1,3}
        datac_setcrosshair(h_ax1, 'va_axes1info', 'ms', 'mV', msg_pos1);
    case {2,4}
        datac_setcrosshair(h_ax1, 'va_axes1info', 'ms', 'nA', msg_pos1);
    otherwise
        datac_setcrosshair(h_ax1, 'va_axes1info', 'ms', 'mV', msg_pos1);
end;
return;